package com.genia.toolbox.projects.csv.business.manager.impl;

import java.util.Map;

import com.genia.toolbox.basics.exception.BundledException;
import com.genia.toolbox.projects.csv.bean.EntityBinder;
import com.genia.toolbox.projects.csv.bean.FieldBinder;
import com.genia.toolbox.projects.csv.business.manager.CheckIfEntityIsNullBinderVisitor;

/**
 * {@link com.genia.toolbox.projects.csv.bean.BinderVisitor} that check if an
 * binder force an entity to be <code>null</code>.
 */
public class CheckIfEntityIsNullBinderVisitorImpl
    implements CheckIfEntityIsNullBinderVisitor
{

  /**
   * the current values of the entities.
   */
  private final ThreadLocal<Map<String, Object>> entitiesValues = new ThreadLocal<Map<String, Object>>();

  /**
   * the values of the field of the csv.
   */
  private final ThreadLocal<Map<String, Object>> fieldsValues = new ThreadLocal<Map<String, Object>>();

  /**
   * the current result.
   */
  private final ThreadLocal<Boolean> entityIsNull = new ThreadLocal<Boolean>();



  /**
   * getter for the entityIsNull property.
   * 
   * @return the entityIsNull
   */
  public boolean isEntityIsNull()
  {
    Boolean res = entityIsNull.get();
    if (res == null) {
      res = false;
      entityIsNull.set(res);
    }
    return res;
  }



  /**
   * clear the setted values to prevent memory leak.
   */
  public void clear()
  {
    this.entitiesValues.remove();
    this.fieldsValues.remove();
    this.entityIsNull.remove();
  }



  /**
   * setter for the entitiesValues property.
   * 
   * @param entitiesValues
   *          the entitiesValues to set
   */
  public void setEntitiesValues(Map<String, Object> entitiesValues)
  {
    this.entitiesValues.set(entitiesValues);
    this.entityIsNull.remove();
  }



  /**
   * setter for the fieldsValues property.
   * 
   * @param fieldsValues
   *          the fieldsValues to set
   */
  public void setFieldsValues(Map<String, Object> fieldsValues)
  {
    this.fieldsValues.set(fieldsValues);
    this.entityIsNull.remove();
  }



  /**
   * visit method for {@link EntityBinder}.
   * 
   * @param binder
   *          the binder to visit
   * @throws BundledException
   *           if an error occured
   * @see com.genia.toolbox.projects.csv.bean.impl.BinderVisitorAdapter#visitEntityBinder(com.genia.toolbox.projects.csv.bean.EntityBinder)
   */
  public void visitEntityBinder(EntityBinder binder)
      throws BundledException
  {
    entityIsNull.set(isEntityIsNull() || (binder.getNullable() && (entitiesValues.get().get(binder.getEntityName()) == null)));
  }



  /**
   * visit method for {@link FieldBinder}.
   * 
   * @param binder
   *          the binder to visit
   * @throws BundledException
   *           if an error occured
   * @see com.genia.toolbox.projects.csv.bean.BinderVisitor#visitFieldBinder(FieldBinder)
   * @see com.genia.toolbox.projects.csv.bean.impl.BinderVisitorAdapter#visitFieldBinder(com.genia.toolbox.projects.csv.bean.FieldBinder)
   */
  public void visitFieldBinder(FieldBinder binder)
      throws BundledException
  {
    entityIsNull.set(isEntityIsNull() || (binder.getNullable() && (fieldsValues.get().get(binder.getFieldName()) == null)));
  }
}